package org.snail.proxy.client;

import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.function.Function;

public class HttpClient {
    private static final String CHAR_SET = "UTF-8";
    private static final CloseableHttpClient HTTP_CLIENT = HttpClients.custom()
            .setDefaultConnectionConfig(ConnectionConfig.custom().setCharset(Charset.forName(CHAR_SET)).build())
            .build();

    public static String get(String url, Map<String, String> headers) throws IOException {
        return send(buildRequest(HttpGet::new, url, headers));
    }

    public static String post(String url, Map<String, String> headers, String body) throws IOException {
        HttpPost request = buildRequest(HttpPost::new, url, headers);
        request.setEntity(new StringEntity(body));
        return send(request);
    }

    public static String put(String url, Map<String, String> headers, String body) throws IOException {
        HttpPut request = buildRequest(HttpPut::new, url, headers);
        request.setEntity(new StringEntity(body));
        return send(request);
    }

    public static String delete(String url, Map<String, String> headers) throws IOException {
        return send(buildRequest(HttpDelete::new, url, headers));
    }

    private static <T extends HttpUriRequest> T buildRequest(Function<String, T> creator, String url, Map<String, String> headers) {
        T request = creator.apply(url);
        headers.entrySet().stream().filter(e -> !e.getKey().equalsIgnoreCase("content-length")).forEach(e -> request.addHeader(new BasicHeader(e.getKey(), e.getValue())));
        return request;
    }

    private static String send(HttpUriRequest request) throws IOException {
        return EntityUtils.toString(HTTP_CLIENT.execute(request).getEntity(), CHAR_SET);
    }
}
